#include <iostream>
#include <string>
#include <sys/wait.h>
#include <assert.h>
#include <sys/types.h>
#include <unistd.h>
#include <cerrno>
#include <string.h>

using namespace std;

int main(){
    //1.创建管道
    int pipefd[2] = {0};
    int n = pipe(pipefd);
    if (n < 0){
        cout << "pipe error, " << errno << ":" << strerror(errno) << endl;
        return 1;
    }
    cout << "pipefd[0]: " << pipefd[0] << endl;
    cout << "pipefd[1]: " << pipefd[1] << endl;
    
    //2.创建子进程
    pid_t id = fork();
    assert(id != -1);
    if(id == 0){
        //子进程
        close(pipefd[0]);
        const string namestr = "child";
        char buffer[1024];
        int cnt = 1;
        while(true){
            sleep(1);
            snprintf(buffer, sizeof(buffer), "%s, cnt: %d, PID: %d", namestr.c_str(), cnt++, getpid());
            write(pipefd[1], buffer, strlen(buffer));
        }

        close(pipefd[1]);
        exit(0);
    }

    //父进程
    close(pipefd[1]);

    char buffer[1024];
    int cnt = 0;
    while(true){
        sleep(1);
        int n = read(pipefd[0], buffer, sizeof(buffer) - 1);
        if(n > 0){
            buffer[n] = '\0';
            cout << "parent, the massage by child: " << buffer << endl;
        }
        else if(n == 0){
            cout << "parent, end" << endl;
            break;
        }
        else{
            cout << "parent, writing error" << endl;
            break;
        }
        if(cnt++ > 4){
            break;
        }
    }

        close(pipefd[0]);

        int status = 0;
        waitpid(id, &status, 0);
        cout << "sig: " << (status & 0x7f) << endl;

        return 0;
}